/*
 * Package il.ac.biu.cs.grossmm.impl.presence
 * File SqlRegistrarTest.java
 * 
 * This is a part of presence service framework prototype. 
 * See javadoc for more information.
 *  
 * Copyright (C) 2006 Grossmann Mark
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package il.ac.biu.cs.grossmm.impl.presence;

import static il.ac.biu.cs.grossmm.api.presence.EntityType.PRESENTITY;
import static il.ac.biu.cs.grossmm.api.presence.EntityType.WATCHER;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import il.ac.biu.cs.grossmm.api.OperationFailedException;
import il.ac.biu.cs.grossmm.api.flow.ActiveDataManager;
import il.ac.biu.cs.grossmm.api.presence.Entity;
import il.ac.biu.cs.grossmm.api.server.Component;
import il.ac.biu.cs.grossmm.api.server.ComponentManager;
import il.ac.biu.cs.grossmm.api.server.ServiceManager;
import il.ac.biu.cs.grossmm.api.sql.SqlDataSource;
import il.ac.biu.cs.grossmm.impl.activeData.ActiveDataManagerImpl;
import il.ac.biu.cs.grossmm.impl.hsqldb.DataSourceAdapter;
import il.ac.biu.cs.grossmm.impl.server.RegistryServer;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class SqlRegistrarTest implements Service, Component {
	RegistryServer server;

	SqlRegistrar registrar;

	@Before
	public void setup()
	{
		server = new RegistryServer();

		server.register("test", this);
		server.registerClass(ActiveDataManager.class,
			ActiveDataManagerImpl.class);
		server.registerClass(SqlRegistrar.class, SqlRegistrar.class);
		server.register(SqlDataSource.class, new DataSourceAdapter(
			"jdbc:hsqldb:file:testpres_db", "sa", ""));

		server.addToStartup("test");

		try {
			server.start();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@After
	public void teardown()
	{
		server.stop();
	}

	@Test
	public void test1()
	{
		try {
			assertNotNull(registrar);
			System.out.println("Deleting identifier alice");
			try {
				registrar.deregisterAlias("Alice");
			} catch( OperationFailedException e) {
			}

			System.out.println("Registering alice");
			Entity e = registrar.registerEntity("Alice", PRESENTITY);

			assertEquals(e.getIdentifiers().size(), 1);
			assertTrue(e.getIdentifiers().contains("Alice"));
			assertTrue(e.is(PRESENTITY));
			assertFalse(e.is(WATCHER));

			e = registrar.getEntity("Alice");

			assertEquals(e.getIdentifiers().size(), 1);
			assertTrue(e.getIdentifiers().contains("Alice"));
			assertTrue(e.is(PRESENTITY));
			assertFalse(e.is(WATCHER));

			System.out.println("Reseting registrar");
			registrar.reset();

			e = registrar.getEntity("Alice");

			assertEquals(e.getIdentifiers().size(), 1);
			assertTrue(e.getIdentifiers().contains("Alice"));
			assertTrue(e.is(PRESENTITY));
			assertFalse(e.is(WATCHER));
			
			System.out.println("Deregistering entity alice");
			registrar.deregister(e);
			
			System.out.println("Ok");
		} catch (OperationFailedException e) {
			e.printStackTrace();
			fail();
		}
	}
	
	@Test
	public void test2(){
		try {
			assertNotNull(registrar);
			System.out.println("Deleting identifier alice");
			try {
				registrar.deregisterAlias("Alice");
			} catch( OperationFailedException e) {
			}

			System.out.println("Registering alice");
			Entity e = registrar.registerEntity("Alice", PRESENTITY);
			registrar.registerRole(e, WATCHER);
			registrar.registerAlias(e, "Alice2");

			assertEquals(e.getIdentifiers().size(), 2);
			assertTrue(e.getIdentifiers().contains("Alice"));
			assertTrue(e.getIdentifiers().contains("Alice2"));
			assertTrue(e.is(PRESENTITY));
			assertTrue(e.is(WATCHER));

			e = registrar.getEntity("Alice");

			assertEquals(e.getIdentifiers().size(), 2);
			assertTrue(e.getIdentifiers().contains("Alice"));
			assertTrue(e.getIdentifiers().contains("Alice2"));
			assertTrue(e.is(PRESENTITY));
			assertTrue(e.is(WATCHER));

			System.out.println("Reseting registrar");
			registrar.reset();

			e = registrar.getEntity("Alice");

			assertEquals(e.getIdentifiers().size(), 2);
			assertTrue(e.getIdentifiers().contains("Alice"));
			assertTrue(e.getIdentifiers().contains("Alice2"));
			assertTrue(e.is(PRESENTITY));
			assertTrue(e.is(WATCHER));
			
			registrar.deregisterAlias("Alice");
			assertEquals(e.getIdentifiers().size(), 1);
			assertFalse(e.getIdentifiers().contains("Alice"));
			
			registrar.deregisterRole(e, PRESENTITY);
			assertFalse(e.is(PRESENTITY));
			assertTrue(e.is(WATCHER));
			
			System.out.println("Deregistering entity alice");
			registrar.deregister(e);
			
			System.out.println("Ok");
		} catch (OperationFailedException e) {
			e.printStackTrace();
			fail();
		}
	}
	
	@Test
	public void test3()
	{
		try {
			assertNotNull(registrar);
			System.out.println("Deleting identifier alice");
			try {
				registrar.deregisterAlias("Alice");
			} catch( OperationFailedException e) {
			}

			System.out.println("Registering alice");
			Entity e = registrar.registerEntity("Alice", PRESENTITY);
			registrar.setProperty(e, "Password", "blabla");
			
			assertEquals("blabla", e.getProperty("Password"));
			
			registrar.setProperty(e, "Format", "pidf");
			assertEquals("blabla", e.getProperty("Password"));
			assertEquals("pidf", e.getProperty("Format"));
			
			registrar.setProperty(e, "Password", "foobar");
			assertEquals("foobar", e.getProperty("Password"));
			assertEquals("pidf", e.getProperty("Format"));
			
			registrar.removeProperty(e, "Format");
			assertEquals("foobar", e.getProperty("Password"));
			assertNull(e.getProperty("Format"));
			
			registrar.reset();
			
			e = registrar.getEntity("Alice");
			assertEquals("foobar", e.getProperty("Password"));
			assertNull(e.getProperty("Format"));
						
			System.out.println("Deregistering entity alice");
			registrar.deregister(e);
		
			
			System.out.println("Ok");
		} catch (OperationFailedException e) {
			e.printStackTrace();
			fail();
		}
	}

	public void start(ServiceManager serviceManager) throws Exception
	{
	}

	public void stop(Exception exception)
	{
	}

	public void terminated(Object serviceHint, Exception e) throws Exception
	{
		throw e;
	}

	public void aborted(Object hint, Exception e) throws Exception
	{
		throw e;
	}

	public void setComponentManager(ComponentManager container)
		throws Exception
	{
		registrar = container.getByClass(SqlRegistrar.class);
	}

}
